package com.tangding.hprose.api.client;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import javax.annotation.PostConstruct;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.tangding.common.exception.GException;
import com.tangding.common.logx.LogHelp;
import com.tangding.common.tools.ErrorConstants;
import com.tangding.common.utils.JacksonUtil;
import com.tangding.config.Config;

import hprose.client.HproseTcpClient;
import hprose.common.HproseException;

/**
 * @description 
 *
 * @author Ranger
 * @version 2017年11月16日_上午11:36:30
 *
 */
@Component
public class HproseAsClient {
//	public static HproseTcpClient client = new HproseTcpClient("tcp4://localhost:3456/");
	public static HproseTcpClient client = null;
//	public static HproseTcpClient client = new HproseTcpClient("tcp4://192.168.3.110:3456/");
	
	@PostConstruct
	public void init() {
		client = new HproseTcpClient(Config.hproseAsClientHost);
		client.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
		client.setKeepAlive(true);
//		client.setConnectTimeout(3000);
		client.setTimeout(5000);
	}
	
	@Scheduled(fixedRate = 2 * 60 * 1000, initialDelay = 60 * 1000)
	public void sendHeartbeat() {//两分钟一个心跳
		try {
			invoke("Heartbeat");
//			System.out.println("发送了一个心跳");
			LogHelp.doLogTesting("heartbeat succ...");
		} catch (GException e) {
			LogHelp.doLogAppErr(e);
		}
	}
	
	public static Object invoke(String operate, Object... data) throws GException {
		long start = System.currentTimeMillis();
		try {
			Object result = null;
			if (data == null || data.length == 0) {
				result = client.invoke(operate);
			}else {
				result = client.invoke(operate, data);
			}
			long end = System.currentTimeMillis();
			LogHelp.doLogFlow("[" + operate + "]invoke cost:" + (end - start));
			return result;
		} catch (Throwable e) {
			long end = System.currentTimeMillis();
			LogHelp.doLogFlow("[" + operate + "]invoke cost(exception):" + (end - start));
			if (e instanceof ExecutionException && e.getCause() instanceof HproseException) {
				throw new GException(ErrorConstants.HPROSE_REMOTE_ERR, ((HproseException) e.getCause()).getLocalizedMessage());
			}else if (e.getCause() instanceof TimeoutException || e instanceof TimeoutException) {
				throw new GException(ErrorConstants.ERR_API_TIMEOUT);
			}else {
				throw new GException(ErrorConstants.ERR_FORWARD, operate + "|" + JacksonUtil.toJson(data) + ":foward err!\r\n" + e.getMessage(), e);
			}
		}
	}
}
